package com.wangyan.javabean2doc;

import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;


/**
 * @author wangyan
 * @date 2024/01/25/17:15
 * @description
 */
@Slf4j
public class JavaBeanToDoc extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        //获取当前在操作的工程上下文
        Project project = e.getData(PlatformDataKeys.PROJECT);

        //获取当前操作的类文件
/*        PsiElement e1 = e.getData(CommonDataKeys.PSI_ELEMENT);
        PsiElement e2 = e.getData(PlatformDataKeys.PSI_ELEMENT);*/

        // 获取当前文件对象
        //Editor editor = e.getData(PlatformDataKeys.EDITOR);
        PsiFile psiFile = e.getData(CommonDataKeys.PSI_FILE);
        List<RowData> rowDataList = new ArrayList<>();

        if (psiFile == null) {
            return;
        }
        // 遍历当前对象的所有属性
        for (PsiElement psiElement : psiFile.getChildren()) {
            if (psiElement instanceof PsiClass) {
                PsiClass psiClass = (PsiClass) psiElement;
                PsiField[] allFields = psiClass.getAllFields();
                for (PsiField psiField : allFields) {
                    String name = "";
                    String desc = "";

                    PsiDocComment docComment = psiField.getDocComment();
                    String comment = Optional.ofNullable(docComment).map(PsiElement::getText).orElse("");
                    if (StringUtils.isNotBlank(comment)) {
                        comment = comment.replace("/**", "").replace("*/", "").trim();
                        String[] split = comment.split("\n");
                        List<String> collect = Arrays.stream(split).map(s -> {
                            if (s.trim().startsWith("*")) {
                                return s.replaceFirst("\\*", "").trim();
                            }
                            return s.trim();
                        }).collect(Collectors.toList());

                        String firstStrO = collect.get(0).trim();
                        String firstStr = firstStrO.substring(0, Math.min(firstStrO.length(), 15));

                        StringBuilder endStr = new StringBuilder();
                        for (int i = 1; i < collect.size(); i++) {
                            endStr.append("\n");
                            endStr.append(collect.get(i));
                        }


                        String[] separatorArr = {" ", "，", ",", "：", ":"};
                        String[] separatorBracket = {"(", "（"};
                        String[] separatorArrDual = {"0-", "1-", "0 ", "1 ", "0:", "1:", "0：", "1："};
                        OptionalInt min;
                        if ((min = Arrays.stream(separatorBracket).mapToInt(firstStr::indexOf).filter(a -> a > 0).min()).isPresent()
                                && (firstStrO.endsWith(")") || firstStrO.endsWith("）"))
                                && Arrays.stream(separatorBracket).noneMatch(s -> StringUtils.countMatches(firstStrO, s) > 1)) {
                            // 有括号 name（1：是 0：否）
                            name = firstStrO.substring(0, min.getAsInt());
                            desc = firstStrO.substring(min.getAsInt() + 1, firstStrO.length() - 1);
                        } else if ((min = Arrays.stream(separatorArr).mapToInt(firstStr::indexOf).filter(a -> a > 0).min()).isPresent()) {
                            // 有分隔符 name,1：是 0：否
                            int asInt = min.getAsInt();
                            name = firstStr.substring(0, asInt);
                            desc = firstStrO.substring(asInt).trim();
                            if (Arrays.stream(separatorArr).anyMatch(desc::startsWith)) {
                                desc = desc.substring(1).trim();
                            }
                            if (Arrays.stream(separatorArr).anyMatch(desc::startsWith)) {
                                desc = desc.substring(1).trim();
                            }
                        } else if ((min = Arrays.stream(separatorArrDual).mapToInt(firstStr::indexOf).filter(a -> a > 0).min()).isPresent()) {
                            name = firstStrO.substring(0, min.getAsInt());
                            desc = firstStrO.substring(min.getAsInt());
                        } else {
                            name = firstStrO;
                        }
                        desc = endStr.insert(0, desc).toString().trim();
                    }

                    PsiAnnotation notEmpty = psiField.getAnnotation("javax.validation.constraints.NotEmpty");
                    PsiAnnotation notNull = psiField.getAnnotation("javax.validation.constraints.NotNull");
                    PsiAnnotation notBlank = psiField.getAnnotation("javax.validation.constraints.NotBlank");
                    PsiAnnotation ignore = psiField.getAnnotation("com.fasterxml.jackson.annotation.JsonIgnore");

                    if (ignore != null) {
                        continue;
                    }

                    String required = "否";
                    if (notBlank != null || notEmpty != null || notNull != null) {
                        required = "是";
                    }

                    String type = psiField.getType().getPresentableText();

                    PsiClass psiClass1 = PsiUtil.resolveClassInClassTypeOnly(psiField.getType());
                    if (psiClass1 != null && psiClass1.isEnum()) {
                        for (PsiField field : psiClass1.getFields()) {
                            if (!(field instanceof PsiEnumConstant)) {
                                type = field.getType().getPresentableText();
                                break;
                            }
                        }
                    }

                    RowData rowData = RowData.builder()
                            .filed(psiField.getName())
                            .name(name)
                            .type(type)
                            .required(required)
                            .desc(desc)
                            .build();
                    if ("id".equals(psiField.getName()) || "rowid".equals(psiField.getName())) {
                        rowDataList.add(0, rowData);
                    } else {
                        rowDataList.add(rowData);
                    }
                }


            }
        }

        if (rowDataList.isEmpty()) {
            //显示对话框
            Messages.showMessageDialog(project, "未查询到数据", "警告", Messages.getInformationIcon());
        }

        log.info("log:{}", rowDataList);

        MyDialogWrapper myDialogWrapper = new MyDialogWrapper(project, rowDataList);
        myDialogWrapper.show();


    }


}
